home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
BCCAPP.ARJ
/
LOWLEVEL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-15
|
9KB
|
411 lines
/*
*
* Low-level systems routines used by Windows TOOLKIT
*
* (C) 1990 Vision Software
*
* $Id: lowlevel.c 1.2002 91/05/03 14:30:40 pcalvin beta Locker: pcalvin $
*
* Comments:
*
* This file consists of the DOS Kludge routines for Binary Screen IO.
* They are implemented (in general) using Borlands Text Library.
*
* Bugs:
*
* None documented.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <new.h>
#include <stdhdr.h>
#include <adl.h>
#include "lowlevel.h"
/*
* Routines to create the "Shadow" for our windows etc..
*/
STATIC CONST CO coShadow = CoEgaFromCoCo(coDarkGray,coBlack);
STATIC VOID ShadowRow(ROW row,COL col1,COL col2);
STATIC VOID ShadowCol(COL col,ROW row1,ROW row2);
/*
* Clears the screen. If using NNANSI.SYS, this resets
* the screen location
*/
STATIC VOID ClearScreen();
/*
* Fatal memory allocation handler..
*/
STATIC VOID FatalMemoryError();
/*
* Run-time dimensions for windows
*/
ROW rowGlobalWindowBottom;
COL colGlobalWindowRight;
/*
* Static array for filling window using gettext/puttext.
* Large enough to hold entire screen..
*/
STATIC CCH cchWindowSize;
STATIC UCHAR *rguchWindow;
/*
* No shadows in monochrome
*/
STATIC BOOL fShadows;
/*
* Generic Environment declarations.
* Allows automatically setting color
* mode.
*/
class ENV
{
public:
ENV(VOID);
~ENV(VOID);
private:
CURSOR crs;
};
/*
* At startup, the cursor is visible. Setting this
* static member to true ensures the cursor is turned
* back on after the program is complete..
*/
BOOL CURSOR::fCurrentState = fTrue;
STATIC ENV env;
/*
* System initialization. Turns off the startup cursor, determines
* the screen lines/max colours etc..
*/
ENV::ENV() : crs(fFalse)
{
text_info y;
/*
* Initialize random number generator
*/
randomize();
/*
* Setup our new-handler..
*/
set_new_handler(FatalMemoryError);
/*
* Determine the startup screen conditions.
*/
ClearScreen();
gettextinfo(&y);
/*
* Only activate shadows if there is a colour screen..
*/
if (y.currmode == C80 || y.currmode == C4350)
fShadows = fTrue;
else
fShadows = fFalse;
/*
* Finally, initialize the rest of the system
*/
rowGlobalWindowBottom = y.screenheight;
colGlobalWindowRight = y.screenwidth;
cchWindowSize = rowGlobalWindowBottom * colGlobalWindowRight * 2;
rguchWindow = new UCHAR[cchWindowSize];
FillWindow(1,1,rowGlobalWindowBottom,colGlobalWindowRight,177,coLightBlue,coBlack);
/*
* Must be initialized here so it knows how many lines are available
*/
HELP::Start();
}
/*
* Resets the system to the startup condition
*/
ENV::~ENV()
{
CursorColor(coWhite,coBlack);
window(1,1,colGlobalWindowRight,rowGlobalWindowBottom);
clrscr();
}
/*
* Executes a dos command. May be Nil, in which case
* we start a new command processor
*/
EXTERN VOID Command(SZ sz)
{
CURSOR crs(fTrue); // Most programs will not do this..
CHAR error;
gettext(1,1,colGlobalWindowRight,rowGlobalWindowBottom,rguchWindow);
CursorColor(coWhite,coBlack);
window(1,1,colGlobalWindowRight,rowGlobalWindowBottom);
clrscr();
/*
* Execute command/shell
*/
if (sz == szNil || sz[0] == chNil)
system("");
else
system(sz);
ClearScreen();
puttext(1,1,colGlobalWindowRight,rowGlobalWindowBottom,rguchWindow);
}
/*
* Creates and executes a does shell
*/
EXTERN VOID DosShell()
{
if (FAskSz("Execute DOS sub-shell?","Press \"Y\" to spawn shell, \"N\" to abort"))
{
Command();
}
}
EXTERN VOID TerminateApplication()
{
if (FAskSz("Terminate Application?","Press \"Y\" to exit, \"N\" to return to application"))
{
exit(0);
}
}
/*
* If using NNANSI.SYSs fast scroll option, this resets
* the screen location
*/
STATIC VOID ClearScreen()
{
printf("\x1b" "[2J");
}
/*
* Set Cursor Color
*/
VOID CursorColor(CO coFore,CO coBack)
{
if (fShadows)
textattr(CoEgaFromCoCo(coFore,coBack));
else if (coBack == coGreen)
textattr(coReverse);
else
textattr(coNormal);
}
/*
* Moves the cursor unconditionally to row,col
*/
VOID SetGlobalRowCol(ROW row,COL col)
{
gotoxy(col,row);
}
/*
* Centers a string output at COL
*/
VOID DisplayCenter(ROW row,COL col,SZ sz,CO coFore,CO coBack)
{
Assert(sz != szNil);
Assert(row > rowNil && row <= rowGlobalWindowBottom);
Assert(col > colNil && col <= colGlobalWindowRight);
DisplayString(row,col - (strlen(sz) >> 1),sz,coFore,coBack);
}
/*
* Displays a window border
*/
VOID DrawBorder(ROW row1,COL col1,ROW row2,COL col2,BD bd,CO coFore,CO coBack)
{
DisplayChar(row1,col1,(bd == bdDouble) ? 201 : 218,coFore,coBack);
FillRow(row1,col1+1,col2-1,(bd == bdDouble) ? 205 : 196,coFore,coBack);
DisplayChar(row1,col2,(bd == bdDouble) ? 187 : 191,coFore,coBack);
FillColumn(row1+1,col1,row2-1,(bd == bdDouble) ? 186 : 179,coFore,coBack);
FillColumn(row1+1,col2,row2-1,(bd == bdDouble) ? 186 : 179,coFore,coBack);
DisplayChar(row2,col1,(bd == bdDouble) ? 200 : 192,coFore,coBack);
FillRow(row2,col1+1,col2-1,(bd == bdDouble) ? 205 : 196,coFore,coBack);
DisplayChar(row2,col2,(bd == bdDouble) ? 188 : 217,coFore,coBack);
if (fShadows)
{
ShadowRow(row2+1,col1+1,col2+1);
ShadowCol(row1+1,col2+1,row2+1);
}
}
/*
* Turn on the shadow..
* First thing to do is make sure the row to effect is entirely visable within
* the screen.
*/
VOID ShadowRow(ROW row,COL colLeft,COL colRight)
{
if (row > rowGlobalWindowBottom)
return;
colRight = Min(colRight,colGlobalWindowRight);
colLeft = Max(colLeft,1);
CCH cchMax = (1+colRight - colLeft) << 1;
SZTEMP sz;
gettext(colLeft,row,colRight,row,sz);
for (CCH cch = 1;cch < cchMax;cch += 2)
sz[cch] = coShadow;
puttext(colLeft,row,colRight,row,sz);
}
/*
* Shadow for the column
* Again, the first thing here is to assert the column lies entirely within the
* boundaries of the screen.
*/
VOID ShadowCol(ROW rowTop,COL col,ROW rowBottom)
{
if (col > colGlobalWindowRight)
return;
rowBottom = Min(rowBottom,rowGlobalWindowBottom);
rowTop = Max(rowTop,1);
CCH cchMax = (1+rowBottom - rowTop) << 1;
SZTEMP sz;
gettext(col,rowTop,col,rowBottom,sz);
for (CCH cch = 1;cch < cchMax;cch += 2)
sz[cch] = coShadow;
puttext(col,rowTop,col,rowBottom,sz);
}
/*
* Display a single character
*/
VOID DisplayChar(ROW row,COL col,CHAR ch,CO coFore,CO coBack)
{
gotoxy(col,row);
CursorColor(coFore,coBack);
putch(ch);
}
/*
* Draw a null terminated string at row,col
*/
VOID DisplayString(ROW row,COL col,SZ sz,CO coFore,CO coBack)
{
Assert(sz != szNil);
Assert(row > rowNil && row <= rowGlobalWindowBottom);
Assert(col > colNil && col <= colGlobalWindowRight);
CursorColor(coFore,coBack);
gotoxy(col,row);
while (*sz != chNil)
putch(*sz++);
}
/*
* Null terminated "HotString" the cch'th character is highlighted..
*/
VOID HotString(ROW row,COL col,CCH cchHotKey,SZ sz,CO coFore,CO coBack)
{
Assert(sz != szNil);
Assert(row > rowNil && row <= rowGlobalWindowBottom);
Assert(col > colNil && col <= colGlobalWindowRight);
DisplayString(row,col,sz,coFore,coBack);
DisplayChar(row,col+cchHotKey,sz[cchHotKey],coBlue,coBack);
}
/*
* Clears/Fills a window with this colour
*/
VOID FillWindow(ROW row1,COL col1,ROW row2,COL col2,CHAR ch,CO coFore,CO coBack)
{
CCH cchMax = (1+row2-row1) * (1+col2-col1) * 2;
CO coEga = CoEgaFromCoCo(coFore,coBack);
CO coMono = (coBack == coGreen) ? coReverse : coNormal;
CO co = (fShadows) ? coEga : coMono;
gettext(col1,row1,col2,row2,rguchWindow);
for (CCH cch = cchNil; cch < cchMax; cch += 2)
{
rguchWindow[cch] = ch;
rguchWindow[cch+1] = co;
}
puttext(col1,row1,col2,row2,rguchWindow);
}
/*
* Binary Keyboard input. DOS KLUDGE: getch() answers Nil if the key
* was a control (Ex. F1) the next answer is that key..
*/
CD CdInput(VOID)
{
REGISTER CD cd = getch();
/*
* Some keys require use to wait for the second answer..
*/
if (cd == cdNil)
cd = getch() << 8;
return (cd);
}
/*
* Implementation for cursor visibility control. Resets cursor to
* previous visibilty upon destruction.
*/
CURSOR::CURSOR(BOOL fShow)
{
/*
* Save the state to be restored after this object goes out of scope
*/
fFinishState = fCurrentState;
fCurrentState = fShow;
Set(fShow);
}
CURSOR::~CURSOR()
{
fCurrentState = fFinishState;
Set(fFinishState);
}
VOID CURSOR::Set(BOOL fShow)
{
_setcursortype(fShow ? _SOLIDCURSOR : _NOCURSOR);
}
/*
* Fatal memory error..
*/
STATIC VOID FatalMemoryError()
{
exit(1);
}